package org.rpgmapper;

import java.util.List;

import org.rpgmapper.bo.Bonus;
import org.rpgmapper.bo.Character;
import org.rpgmapper.bo.Hero;
import org.rpgmapper.database.RPGMapperOpenHelper;
import org.rpgmapper.skirmish.SkirmishListener;
import org.rpgmapper.skirmish.SkirmishManager;
import org.rpgmapper.view.ConfigureSkirmishView;
import org.rpgmapper.view.MenuInfoView;
import org.rpgmapper.view.SkirmishInfoView;

import android.content.ClipData;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.jme3.input.TouchInput;
import com.jme3.input.controls.TouchTrigger;


import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.logging.Level;
import org.rpgmapper.view.StatsView;

public class Main extends AndroidHarness implements JmeInitListener {

    private StatsView statsView = null;
    protected int splashPicID = R.drawable.rpgmapper;
    private ImageView splashImageView = null;
    private FrameLayout frameLayout = null;

    public Main() {
        // Set the application class to run
        appClass = "org.rpgmapper.JmeMain";
        // eglConfigType = ConfigType.FASTEST; // Default
        eglConfigType = ConfigType.BEST;
        // Exit Dialog title & message
        exitDialogTitle = "Exit?";
        exitDialogMessage = "Press Yes";
        // Edit: 25.06.2011: Enable verbose logging
        eglConfigVerboseLogging = false;
        // Edit: 30.06.2011: Choose screen orientation
        screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        // Edit 12.07.2011: Invert the MouseEvents X (default = true)
        mouseEventsInvertX = true;
        // Edit 05.07.2011: Invert the MouseEvents Y (default = true)
        mouseEventsInvertY = true;
        mouseEventsEnabled = true;

    }
    // private ScaleGestureDetector mScaleDetector;
    private GestureDetector mScrollDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        app.setInitListener(this);
//        setContentView(iv);
        // requestWindowFeature(Window.FEATURE_NO_TITLE);
        // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        // WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //app.add
        setContentView(R.layout.main);
        layoutDisplay();


//        ((RelativeLayout) findViewById(R.id.main_container)).addView(iv, 0);
//        app.addLoadingListener(new LoadingListener() {
//
//            public void onLoad() {
//                ((RelativeLayout) findViewById(R.id.main_container)).removeView(iv);
//                
//            }
//        });


        RPGMapperOpenHelper helper = new RPGMapperOpenHelper(this);
        // helper.deleteAllCharacters();
        // Mock.addCharacters(this, helper);
        // Mock.addMonsters(this, helper);

        System.err.println("### HEROES");
        List<Character> chars = helper.getAllHeroes();
        for (Character character : chars) {
            System.err.println(character.toString());
        }
        System.err.println("### MONSTERS");
        chars = helper.getAllMonsters();
        for (Character character : chars) {
            System.err.println(character.toString());
        }
        System.err.println("#########################");
        /**
         * Fin insertion
         */
        /**
         * on init le skirmish
         */
        // SkirmishManager.getInstance().setCharacters(helper.getAllCharacters());
        SkirmishManager.getInstance().setSkirmishListener(
                new SkirmishListener() {

                    public void onBeginSkirmish() {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                        siv.hide();
                        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
                        miv.hide();
                        ConfigureSkirmishView csv = (ConfigureSkirmishView) findViewById(R.id.menu_create_map);
                        csv.toggle();
                    }

                    public void onChangeRound(int nextRoundNumber) {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
                        miv.hide();
                    }

                    public void onChangeCharacter(Character nextCharacter) {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
                        miv.hide();
                    }

                    public void onEndSkirmish() {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
                        miv.hide();
                    }

                    public void onAddBonus(Bonus bonus) {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateBonusInfos();
                    }

                    public void onBonusEnd(Bonus bonus) {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateBonusInfos();
                    }

                    public void onAddCharacter(Character character) {
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                    }
                    
                    public void onRemoveCharacter(Character character) {
                        Main.getJmeApp().removeCharacter(character);
                        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
                        siv.updateRoundInfos();
                        siv.updateBonusInfos();
                    }
                    
                   

                    public void onWantToAddCharacter() {
                        ConfigureSkirmishView csv = (ConfigureSkirmishView) findViewById(R.id.menu_create_map);
                        csv.selectTabAtIndex(1);
                        csv.show();
                    }

                    public void onShowCharacterInfo(Character character) {

                        // si la vue a deja ete creee, on la supprime carrement
                        if (statsView != null) {
                            ((RelativeLayout) findViewById(R.id.main_container)).removeView(statsView);
                        }
                        // Creation de la vue des stats d'un perso
                        statsView = new StatsView(Main.this);
                        // on y met le perso Foa
                        statsView.setCharacter(character);
                        // On cache la vue pour pouvoir l'ajouter à l'affichage sans qu'elle apparaisse
                        statsView.setVisibility(View.GONE);
                        // on l'ajoute
                        ((RelativeLayout) findViewById(R.id.main_container)).addView(statsView);
                        // on change ses parametres d'affichage (hauteur et margins)
                        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) statsView.getLayoutParams();
                        params.height = 380;
                        params.width = 1250;
                        params.setMargins(10, 10, 10, 10);
                        // on met le listener pour indiquer ce que le bouton OK de la vue va faire
                        // Pour le moment, on ne fait que la detruire
                        statsView.setOKClickListener(new View.OnClickListener() {

                            public void onClick(View v) {
                                ((RelativeLayout) findViewById(R.id.main_container)).removeView(statsView);
                            }
                        });
                        // on rend la vue visible
                        statsView.setVisibility(View.VISIBLE);
//                        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
//                        miv.setCharacter(SkirmishManager.getInstance().getCharacter());
//                        miv.toggle();
                    }
                });
//        SkirmishManager.getInstance().addBonus(
//                new Bonus(5, "+3 VOL", BonusType.CHARACTER));
//        SkirmishManager.getInstance().addBonus(
//                new Bonus(5, "+10 DAM", BonusType.MONSTER));
        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
        siv.updateRoundInfos();
        siv.updateBonusInfos();

        mScrollDetector = new GestureDetector(this, new ScrollGestureListener());

        /*
         * findViewById(R.id.sinusoide).setOnClickListener(new
         * View.OnClickListener() { public void onClick(View v) {
         * PropertyValuesHolder pvhX =
         * PropertyValuesHolder.ofFloat("translationX", 1200f);
         * PropertyValuesHolder pvhY =
         * PropertyValuesHolder.ofFloat("translationY", 400f); ObjectAnimator
         * anim =
         * ObjectAnimator.ofPropertyValuesHolder(findViewById(R.id.sinusoide),
         * pvhX, pvhY); pvhY.setEvaluator(new TypeEvaluator() { public Object
         * evaluate(float fraction, Object startValue, Object endValue) { //
         * y=a*sin(x/b) o� a g�re l'amplitude et b la p�riode double result;
         * double x = (1200f*fraction); result = 80f*Math.sin(x/40.0); return
         * result; } }); anim.setDuration(10000); anim.start(); } });
         */

        /*
         * findViewById(R.id.bg_interface).setOnTouchListener(new
         * View.OnTouchListener() { public boolean onTouch(View v, MotionEvent
         * event) { if (event.getPointerCount() > 1) {
         * //mScaleDetector.onTouchEvent(event); } else {
         * mScrollDetector.onTouchEvent(event); } return true; } });
         */
        glView.setOnDragListener(onDragListener);
        

        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) findViewById(
                R.id.menu_create_map).getLayoutParams();
        lp.setMargins(lp.leftMargin, lp.topMargin, lp.rightMargin,
                getSkirmishInfoVisibleHeight());
    }

    public void layoutDisplay() {
        logger.log(Level.INFO, "Splash Screen Picture Resource ID: {0}", splashPicID);
        if (splashPicID != 0) {
            LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

            frameLayout = new FrameLayout(this);
            frameLayout.setLayoutParams(lp);

            splashImageView = new ImageView(this);
            splashImageView.setImageResource(splashPicID);
            splashImageView.setLayoutParams(lp);

            frameLayout.addView(glView);
            frameLayout.addView(splashImageView, lp);

            ((RelativeLayout) findViewById(R.id.main_container)).addView(frameLayout, 0);

            logger.log(Level.INFO, "Splash Screen Created");
        } else {
            logger.log(Level.INFO, "Splash Screen Skipped.");
            ((RelativeLayout) findViewById(R.id.main_container)).addView(glView, 0);

        }

    }

    public void removeSplashScreen() {
        logger.log(Level.INFO, "Splash Screen Picture Resource ID: {0}", splashPicID);
        if (splashPicID != 0) {
            if (frameLayout != null) {
                if (splashImageView != null) {
                    this.runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            splashImageView.setVisibility(View.INVISIBLE);
                            frameLayout.removeView(splashImageView);
//                            ((RelativeLayout) findViewById(R.id.main_container)).removeView(frameLayout);
//                            ((RelativeLayout) findViewById(R.id.main_container)).addView(glView, 0);

                        }
                    });
                } else {
                    logger.log(Level.INFO, "splashImageView is null");
                }
            } else {
                logger.log(Level.INFO, "frameLayout is null");
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
        miv.hide();
        ConfigureSkirmishView csv = (ConfigureSkirmishView) findViewById(R.id.menu_create_map);
        csv.hide();
    }

    public int getSkirmishInfoVisibleHeight() {
        SkirmishInfoView siv = (SkirmishInfoView) findViewById(R.id.skirmish);
        return siv.getVisibleHeight();
    }

    public void onInit() {
        JmeMain.getApplicationContext().getSelectionManager().addCharacterListener(SkirmishManager.getInstance());
        app.getInputManager().addMapping(ESCAPE_EVENT, new TouchTrigger(TouchInput.KEYCODE_BACK));
        app.getInputManager().addListener(this, new String[]{ESCAPE_EVENT});
        removeSplashScreen();
    }

    private class ScrollGestureListener implements
            GestureDetector.OnGestureListener {

        public ScrollGestureListener() {
        }

        public boolean onDown(MotionEvent e) {
            return false;
        }

        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            return false;
        }

        public void onLongPress(MotionEvent e) {
        }

        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            return false;
        }

        public void onShowPress(MotionEvent e) {
        }

        public boolean onSingleTapUp(MotionEvent e) {
            if (SkirmishManager.getInstance().getCharacter() instanceof Hero) {
                MenuInfoView miv = (MenuInfoView) findViewById(R.id.menu);
                miv.setCharacter(SkirmishManager.getInstance().getCharacter());
                miv.toggle();
            }
            return false;
        }
    }
    private OnDragListener onDragListener = new View.OnDragListener() {

        public boolean onDrag(View v, DragEvent event) {
            // Defines a variable to store the action type for the incoming
            // event
            final int action = event.getAction();
            // Handles each of the expected events
            switch (action) {
                // on return true pour indiquer au systeme qu'on est receveur
                // potentiel
                case DragEvent.ACTION_DRAG_STARTED:
                    return (true);
                case DragEvent.ACTION_DRAG_ENTERED:
                    return (true);
                case DragEvent.ACTION_DRAG_EXITED:
                    return (true);
                case DragEvent.ACTION_DROP:
                    ClipData.Item item = event.getClipData().getItemAt(0);
                    CharSequence dragData = item.getText();
                    int characterId = Integer.parseInt(dragData.toString());
                    RPGMapperOpenHelper helper = new RPGMapperOpenHelper(Main.this);
                    if (characterId > 0) {
                        Character droppedCharacter = helper.getCharacterById(characterId);
                        app.enlistCharacter(droppedCharacter, event.getX(), glView.getHeight() - event.getY());
                        SkirmishManager.getInstance().addCharacter(droppedCharacter);
                    }
                    return (true);
                case DragEvent.ACTION_DRAG_ENDED:
                    return (true);
                default:
                    break;
            }
            ;
            return false;
        }
    };

    public static JmeMain getJmeApp() {
        return app;
    }
}